import datetime
import os
import json
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.http import Http404, JsonResponse
from django.shortcuts import render_to_response, redirect
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from django.template import RequestContext
from MyBlog.settings import MEDIA_ROOT, QINIU_ACCESS_KEY, QINIU_SECRET_KEY, QINIU_PREFIX, QINIU_WATERMARK
from urllib.parse import urljoin
from qiniu import Auth, put_file, etag
from .models import Files, Article, Archive, Catagory, Tag, Visitor, Comment, BrowseRecord
from django.db.models import Q
from django.contrib.auth import logout
from django.db import connection
from .IpInfo import get_ip_address
from .WeatherInfo import get_weather_info_by_city
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


@login_required
def blog_dashboard(request):
    uv_num = Visitor.objects.count()
    pv_num = BrowseRecord.objects.count()
    retention_rate = round(pv_num / uv_num, 2)
    comment_num = Comment.objects.count()

    cursor = connection.cursor()
    browse_data_sql = 'select city, count(*) from xBlog_browserecord as xb,xBlog_visitor as xv where ' \
                      + 'xb.visitor_id=xv.id group by city order by count(*) desc limit 7'
    cursor.execute(browse_data_sql)
    browse_data = cursor.fetchall()
    article_visit_sql = 'select title,visit_count,count(xc.id)  from xBlog_article as xa left join xBlog_comment ' \
                        + 'as xc on xa.id=xc.article_id_id group by xa.id order by visit_count desc, count(xc.id) ' \
                        + 'desc, xa.date_time desc limit 9'
    cursor.execute(article_visit_sql)
    article_visit_data = cursor.fetchall()

    ip_address = get_ip_address(request)
    try:
        visitor = Visitor.objects.get(ip_address=ip_address)
    except Visitor.DoesNotExist:
        visitor = Visitor.get_visitor(ip_address=ip_address)
    city = '天津' if visitor.city == '火星' else visitor.city
    if city:
        tmp, cond = get_weather_info_by_city(city)
        if not tmp or not cond:
            tmp, cond = '没找到', '囧'
    else:
        tmp, cond = '没找到', '囧'

    browse_line_data_sql = 'select date_format(ADDDATE(date_time,INTERVAL 8 HOUR),"%c/%e"),count(*),(select count(*) ' \
                           'from xBlog_comment where date_format(ADDDATE(date_time,INTERVAL 8 HOUR),"%Y-%m-%d")' \
                           '=date_format(ADDDATE(submit_time,INTERVAL 8 HOUR),"%Y-%m-%d")) from xBlog_browserecord ' \
                           'group by date_format(ADDDATE(date_time,INTERVAL 8 HOUR),"%Y-%m-%d") order by date_time desc limit 7'
    cursor.execute(browse_line_data_sql)
    browse_line_data = cursor.fetchall()

    today_date = datetime.date.today()

    birthday = (str(today_date.year) if today_date <= datetime.date(today_date.year, 4, 2) else str(
        today_date.year + 1)) + '-04-02'
    memo = (str(today_date.year) if today_date <= datetime.date(today_date.year, 4, 30) else str(
        today_date.year + 1)) + '-04-30'

    days_remind = {'建站': '2016-04-01', '爸妈银婚': '2017-05-10', '女盆友生日': birthday,
                   '纪念日': memo}

    return render_to_response('xBlog_admin/admin_home.html',
                              {'uv_num': uv_num, 'pv_num': pv_num, 'retention_rate': retention_rate,
                               'comment_num': comment_num, 'browse_data': browse_data,
                               'article_visit_data': article_visit_data, 'temperature': tmp,
                               'condition': cond, 'cur_city': city, 'browse_line_data': reversed(browse_line_data),
                               'days_remind': days_remind},
                              context_instance=RequestContext(request))


@login_required
def blog_articles(request):
    if request.method == 'GET':
        condition = request.GET.get('q', None)
        if condition and condition.strip():
            condition = condition.strip()
            tags = Tag.objects.filter(tag_name__icontains=condition)
            archives = Archive.objects.filter(archive_name__icontains=condition)
            catagories = Catagory.objects.filter(catagory_name__icontains=condition)
            articles = Article.objects.filter(
                Q(title__icontains=condition) | Q(archive__in=archives) | Q(
                    catagory__in=catagories)).prefetch_related()
            if tags:
                temp_articles = set(articles)
                for tag in tags:
                    temp_articles.update(set(tag.article_set.all()))
                articles = list(temp_articles)
        else:
            articles = Article.objects.all()

        total_num = len(articles)

        page = request.GET.get('page')

        paginator = Paginator(articles, 20)
        try:
            post_list = paginator.page(page)
        except PageNotAnInteger:
            post_list = paginator.page(1)
        except EmptyPage:
            post_list = paginator.page(paginator.num_pages)

        return render_to_response('xBlog_admin/admin_article_list.html',
                                  {'articles': post_list, 'condition': condition, 'total': total_num},
                                  context_instance=RequestContext(request))
    else:
        raise Http404


@login_required
def blog_article_add(request):
    try:
        max_id = Article.objects.all().order_by('-pk')[0].pk
    except IndexError:
        max_id = 1
    files = Files.objects.all()
    return render_to_response('xBlog_admin/admin_article.html', {'files': files, 'article_id': max_id + 1},
                              context_instance=RequestContext(request))


@login_required
def blog_article_change(request, article_id):
    try:
        article = Article.objects.get(pk=article_id)
    except Article.DoesNotExist:
        raise Http404
    files = Files.objects.all()

    return render_to_response('xBlog_admin/admin_article.html', {'article': article, 'files': files},
                              context_instance=RequestContext(request))


@login_required
def blog_article_delete(request, article_id):
    try:
        article = Article.objects.get(pk=article_id)
    except Article.DoesNotExist:
        raise Http404
    article.delete()

    articles = Article.objects.all()
    return render_to_response('xBlog_admin/admin_article_list.html', {'articles': articles},
                              context_instance=RequestContext(request))


@login_required
def upload_file(request):
    bucket_name = 'xblog-pictures'

    if request.method == 'POST':
        file = request.FILES.get('upload-file', None)
        if file:
            file_id = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
            filename = file_id + os.path.splitext(file.name)[1]
            path = default_storage.save(filename, ContentFile(file.read()))
            localfile = os.path.join(MEDIA_ROOT, path)
            q = Auth(QINIU_ACCESS_KEY, QINIU_SECRET_KEY)
            token = q.upload_token(bucket_name, filename, 3600)
            ret, info = put_file(token, filename, localfile)
            assert ret['key'] == filename
            assert ret['hash'] == etag(localfile)
            os.remove(localfile)
            url = urljoin(QINIU_PREFIX, filename + ('-' if QINIU_WATERMARK else '') + '-'.join(QINIU_WATERMARK))

            uploaded_file = Files(filename=file.name, file_id=file_id, url=url)
            uploaded_file.save()

            return JsonResponse({'filename': file.name, 'url': url, 'file_id': file_id})
        else:
            raise Http404
    else:
        raise Http404


@login_required
def save_article(request):
    if request.method == 'POST':
        article_id = request.POST.get('id', None)
        title = request.POST.get('title', None)
        catagory_id = request.POST.get('catagory', None)
        archive_id = request.POST.get('archive', None)
        tag_names = json.loads(request.POST.get('tags', None))
        content = request.POST.get('content', None)
        try:
            article = Article.objects.get_or_create(pk=article_id)
            catagory = Catagory.objects.get(pk=catagory_id)
            archive = Archive.objects.get(pk=archive_id)
            tags = Tag.objects.filter(tag_name__in=tag_names)
            article[0].change(title, catagory, archive, tags, content)
        except Catagory.DoesNotExist:
            raise Http404

        except Archive.DoesNotExist:
            raise Http404
        except Tag.DoesNotExist:
            raise Http404
        except ValueError as e:
            return JsonResponse({'result': False, 'message': str(e)})

        return JsonResponse({'result': True})
    else:
        raise Http404


@login_required
def logout_view(request):
    logout(request)
    return redirect(reverse('blog_dashboard'))
